home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 013 / dskwatch.arc / DSKWATCH.ASM next >
Encoding:
Assembly Source File  |  1985-05-15  |  5.8 KB  |  110 lines

  1. Figure 1:  The assembly language source code for DSKWATCH.COM
  2.  
  3.  
  4. INTERRUPTS      SEGMENT AT 0H    ;This is where the disk interrupt
  5.         ORG     13H*4            ;holds the address of its service routine
  6. DISK_INT        LABEL   DWORD
  7. INTERRUPTS      ENDS
  8.  
  9. SCREEN  SEGMENT AT 0B000H       ;A dummy segment to use as the
  10. SCREEN  ENDS                    ;Extra Segment so we can write to the display
  11.  
  12. CODE_SEG        SEGMENT
  13.         ASSUME  CS:CODE_SEG
  14.         ORG     100H            ;ORG = 100H to make this into a .COM file
  15. FIRST:  JMP     LOAD_WATCH      ;First time through jump to initialize routine
  16.  
  17.         MSG_PART_1      DB      'Disk error: '  ;Here are the error messages.
  18.         MSG_PART_2      DB      'No response Failed Seek NEC Error   '
  19.                         DB      'Bad CRC SeenDMA Overrun Impos Sector'
  20.                         DB      'No Addr MarkW. ProtectedErr Unknown '
  21.         FIRST_POSITION  DW      ?               ;Position of 1st char on screen
  22.         FLAGS           DW      ?
  23.         SCREEN_SEG_OFFSET       DW      0       ;0 for mono, 8000H for graphics
  24.         OLD_DISK_INT            DD      ?       ;Location of old disk interrupt
  25.         RET_ADDR                LABEL DWORD     ;Used in fooling around with
  26.         RET_ADDR_WORD           DW 2 DUP(?)     ; stack.
  27.  
  28. DISK_WATCH      PROC    FAR            ;The Disk interrupt will now come here.
  29.         ASSUME  CS:CODE_SEG
  30.         PUSHF                   ;First, call old disk interrupt
  31.         CALL    OLD_DISK_INT
  32.         PUSHF                   ;Save the flags in memeory location "FLAGS"
  33.         POP     FLAGS           ; (cunning name).
  34.         JC      ERROR           ;If there was an error, carry flag will have
  35.         JMP     FIN             ; been set by Disk interrupt.
  36. ERROR:  PUSH    AX              ;AH has the status of the error
  37.         PUSH    CX              ;Push all used registers for politeness
  38.         PUSH    DX
  39.         PUSH    DI
  40.         PUSH    SI
  41.         PUSH    ES
  42.         LEA     SI,MSG_PART_1   ;Always print "Disk Error: " part.
  43.         ASSUME  ES:SCREEN               ;Use screen as extra segment
  44.         MOV     DX,SCREEN
  45.         MOV     ES,DX
  46.         MOV     DI,SCREEN_SEG_OFFSET    ;DI will be pointer to screen postion
  47.         ADD     DI,FIRST_POSITION       ;Add to point to desired area on screen
  48.         CALL    WRITE_TO_SCREEN    ;This writes 12 characters from [SI] to [DI]
  49.         MOV     DH,80H                  ;Initialize for later comparisons
  50.         MOV     CX,7                    ;Loop seven times
  51. E_LOOP: CMP     AH,DH                   ;Are error code and DH the same?
  52.         JE      E_FOUND                 ;If yes, Error has been found
  53.         ADD     SI,12                   ;Point to next error message
  54.         SHR     DH,1                    ;Divide DH by 2
  55.         LOOP    E_LOOP                  ;Keep going until matched or DH=0
  56.         CMP     AH,3                    ;Error Code not even number; 3 perhaps?
  57.         JE      E_FOUND                 ;If yes, have found the error
  58.         ADD     SI,12                   ;Err unknown; unknown error returned
  59. E_FOUND:CALL    WRITE_TO_SCREEN         ;Write the error message to screen
  60.         POP     ES      ;Having done Pushes, here are the Pops
  61.         POP     SI
  62.         POP     DI
  63.         POP     DX
  64.         POP     CX
  65.         POP     AX
  66. FIN:    POP     RET_ADDR_WORD           ;Fooling with the stack. We want to
  67.         POP     RET_ADDR_WORD[2]        ;preserve the flags but the old flags
  68.         ADD     SP,2                    ;are still on the stack. First remove
  69.         PUSH    FLAGS                   ;return address, then flags. Fill flags
  70.         POPF                            ;from "FLAGS", return to correct addr.
  71.         JMP     RET_ADDR
  72. DISK_WATCH      ENDP
  73.  
  74. WRITE_TO_SCREEN PROC    NEAR    ;Puts 12 characters on the screen
  75.         MOV     CX,12           ;Loop 12 times
  76. W_LOOP: MOVS    ES:BYTE PTR[DI],CS:[SI] ;Move to the screen
  77.         MOV     AL,7            ;Move screen attribute into screen buffer
  78.         MOV     ES:[DI],AL
  79.         INC     DI              ;Point to next byte in screen buffer
  80.         LOOP    W_LOOP          ;Keep going until done.
  81.         RET                     ;Exeunt
  82. WRITE_TO_SCREEN ENDP
  83.  
  84. LOAD_WATCH        PROC    NEAR  ;This procedure intializes everything
  85.         ASSUME  DS:INTERRUPTS   ;The data segment will be the Interrupt area
  86.         MOV     AX,INTERRUPTS
  87.         MOV     DS,AX
  88.  
  89.         MOV     AX,DISK_INT         ;Get the old interrupt service routine
  90.         MOV     OLD_DISK_INT,AX     ;address and put it into our location
  91.         MOV     AX,DISK_INT[2]      ;OLD_DISK_INT so we can call it.
  92.         MOV     OLD_DISK_INT[2],AX
  93.  
  94.         MOV     DISK_INT,OFFSET DISK_WATCH  ;Now load the address of DskWatch
  95.         MOV     DISK_INT[2],CS         ;routine into the Disk interrupt
  96.  
  97.         MOV     AH,15                   ;Ask for service 15 of INT 10H
  98.         INT     10H                     ;This tells us how display is set up
  99.         SUB     AH,25                   ;Move to twenty five places before edge
  100.         SHL     AH,1                    ;Mult by two (char & attribute bytes)
  101.         MOV     BYTE PTR FIRST_POSITION,AH      ;Set screen cursor
  102.         TEST    AL,4                    ;Is it a monochrome display?
  103.         JNZ     EXIT                    ;Yes - jump out
  104.         MOV     SCREEN_SEG_OFFSET,8000H ;No - set up for graphics display
  105. EXIT:   MOV     DX,OFFSET LOAD_WATCH    ;Set up everything but this program to
  106.         INT     27H                     ;stay and attach itself to DOS
  107. LOAD_WATCH        ENDP
  108.         CODE_SEG        ENDS
  109.         END     FIRST   ;END "FIRST" so 8088 will go to FIRST first.
  110.